﻿using System.Threading;

namespace defical_gui
{
    public partial class main
    {
        private void go()
        {
            this.isProcessing = true;
            int numThreads = (System.Environment.ProcessorCount * 3)/2;
            Thread[] threads = new Thread[numThreads];
            int start;
            int end = 0;
            txtResult.Dispatcher.BeginInvoke(new StringDelegate(printMessage), new object[] { 200, "" });
            for (int i = 0; i < numThreads; i++)
            {
                threads[i] = new Thread(goBT);
                threads[i].IsBackground = true;
                start = end + 1;
                end = start + ((this.numVerMain + this.numVerDef + 1) / 2) / numThreads;
                if (i == numThreads - 1) { end = (this.numVerMain + this.numVerDef + 1) / 2; }
                threads[i].Start(new int[] { start, end, i });
            }
            while (this.isProcessing)
            {
                Thread.Sleep(100);
                if (!this.isProcessing) { break; }
                bool threadIsProcessing = true;
                switch (this.isFindEverything)
                {
                    case true:
                        {
                            threadIsProcessing = false;
                            for (int i = 0; i < numThreads; i++)
                            {
                                if (threads[i].IsAlive)
                                {
                                    threadIsProcessing = true;
                                    break;
                                }
                            } 
                            break;
                        }
                    case false:
                        {
                            threadIsProcessing = true;
                            for (int i = 0; i < numThreads; i++)
                            {
                                if (!threads[i].IsAlive)
                                {
                                    threadIsProcessing = false;
                                    break;
                                }
                            }
                            break;
                        }
                }
                this.isProcessing = threadIsProcessing;
            }
            txtResult.Dispatcher.BeginInvoke(new StringDelegate(printMessage), new object[] { 201, "" });
            for (int i = 0; i < numThreads; i++)
                if (threads[i].IsAlive)
                    threads[i].Abort();
        }
        private void goBT(object o)
        {
            int[] args = o as int[];
            int start = args[0];
            int end = args[1];
            int threadID = args[2];
            for (int i = start; i <= end; i++)
            {
                if (this.isProcessing)
                {
                    libbacktrack.Backtrack myWork = new libbacktrack.Backtrack(this.graphType, this.numVerMain, this.numVerDef, i,this.isFindEverything);
                    myWork.Walk();
                    if (this.isProcessing)
                    {
                        if (myWork.IsSemt)
                        {
                            txtResult.Dispatcher.BeginInvoke(new StringDelegate(printMessage), new object[] { 400, "" });
                            txtResult.Dispatcher.BeginInvoke(new StringDelegate(printMessage), new object[] { 0, myWork.Result });
                            if (!this.isFindEverything) { break; }
                        }
                        else { txtResult.Dispatcher.BeginInvoke(new StringDelegate(printMessage), new object[] { 401, i.ToString() }); }
                    }
                }
            }
        }
    }
}
